package com.smh.demo1.a30;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletRegistrationBean;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.*;
import org.springframework.web.servlet.mvc.Controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author shiminghui
 * @date 2025/5/4 9:57
 * @description: TODO
 */
@Configuration
public class WebConfig {

    @Bean
    public TomcatServletWebServerFactory tomcatServletWebServerFactory() {
        TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
        factory.setPort(8080);
        return factory;
    }

    @Bean
    public DispatcherServlet dispatcherServlet() {
        DispatcherServlet dispatcherServlet = new DispatcherServlet();
        return dispatcherServlet;
    }

    @Bean
    public DispatcherServletRegistrationBean dispatcherServletRegistrationBean() {
        DispatcherServletRegistrationBean registrationBean = new DispatcherServletRegistrationBean(dispatcherServlet(), "/");
        registrationBean.setName("dispatcherServlet"); // 设置DispatcherServlet的名称
        registrationBean.setLoadOnStartup(0);
        return registrationBean;
    }

    @Bean("/c3")
    public Controller c3() {
        return new Controller() {
            @Override
            public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
                response.getWriter().print("""
                        <h1>c3</h1>
                        """);
                return null;
            }
        };
    }
//    @Bean
//    // 调用对应的Bean的方法
//    public SimpleControllerHandlerAdapter simpleControllerHandlerAdapter(){
//        SimpleControllerHandlerAdapter simpleControllerHandlerAdapter = new SimpleControllerHandlerAdapter();
//        return simpleControllerHandlerAdapter;
//    }

    //    @Bean
//    // 解析路径,匹配Bean的名字,找到对应的Bean
//    public BeanNameUrlHandlerMapping beanNameUrlHandlerMapping(){
//        BeanNameUrlHandlerMapping beanNameUrlHandlerMapping = new BeanNameUrlHandlerMapping();
//        return beanNameUrlHandlerMapping;
//    }
    // 自己实现BeanNameUrlHandlerMapping
    @Component
    public static class MyHandlerMapping implements HandlerMapping, InitializingBean, ApplicationContextAware {

        private ApplicationContext context;
        private Map<String, Controller> collect;

        @Override
        public HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
            String uri = request.getRequestURI();
            if (collect.containsKey(uri)) {
                Controller controller = collect.get(uri);
                return new HandlerExecutionChain(controller); // 返回是一个执行连,是用来执行拦截器方法的
            }
            return null;
        }


        @Override
        public void afterPropertiesSet() throws Exception {
            // 初始化
            // 从容器中查找所有Controller
            Map<String, Controller> beansOfType = context.getBeansOfType(Controller.class);
            // 筛选Bean,只要/ 开头的
            collect = beansOfType.entrySet().stream()
                    .filter(e -> e.getKey().startsWith("/"))
                    .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue()));
        }

        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            context = applicationContext;
        }
    }

    @Component
    public static class SimpleControllerHandlerAdapter implements HandlerAdapter {
        @Override
        public boolean supports(Object handler) {
            return handler instanceof Controller;
        }

        @Override
        public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            Controller controller = (Controller) handler;
            controller.handleRequest(request, response);
            return null; // 返回null,表示不返回数据,直接返回,即不走视图渲染
        }

        @Override // 用于处理304请求的,即判断是否有更新,若无数据修改,则使用浏览器缓存
        public long getLastModified(HttpServletRequest request, Object handler) {
            return -1;
        }
    }

    @Component("/c1")
    public static class C1 implements Controller {
        @Override
        public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
            response.getWriter().print("""
                    <h1>c1</h1>
                    """);
            return null;
        }
    }

    @Component("/c2")
    public static class C2 implements Controller {
        @Override
        public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
            response.getWriter().print("""
                    <h1>c2</h1>
                    """);
            return null;
        }
    }

}
